#include <system.h>
#include <std.h>
#include <fdc.h>
#include <pio.h>
#include <error.h>
#include <type.h>
#include <memory.h>
#include <dint.h>
#include <keyboard.h>
#include <sched.h>
#include <asm.h>
#include <text.h>
#include <irq.h>
#include <ui.h>
#include <ksetting.h>

#define MAX_OBJ 20
#define MAX_DAT 20
#define MAX_LINK 10
#define MAX_DESC 32
#define MAX_DT 20


/*Possible link types:*/
#define LT_NC 0	//Unconditional link. Link without checking any condition
#define LT_C 1 //Conditional link
#define LT_SEQ 0	//Sequential link
#define LT_CONC 0x10
#define LT_DEAD 0x20	//Dead link... Just to keep the object in memory and not execute it
/*For concurrent link a new control is created that executes the link with other links and when the link
returns the control is ended.*/

/*A link which specifies a condition which if satisfied, the link is taken.*/

/*Possible condition types:*/
#define CON_E 0	//Equal
#define CON_G 1	//Greater
#define CON_L 2	//Less
#define CON_GE 3
#define CON_LE 4

struct object;



struct link	{
	struct object *link_object;
	int c_type;	//Condition type
	int link_type;
};

/*The main object structure.
It includes a function for core objects which is written in C and linked during initialization before the rt system
starts up.
*/

struct object	{
	void (*fn)(struct object *this_obj);
	struct link *links[MAX_LINK];
};

/*Object description table
This includes the object physical address and its corresponding name for the user*/
static struct obj_desctable	{
	struct object *x;
	char desc[MAX_DESC];
}obj_desc[MAX_OBJ];


/*Registers an object in the descriptor table with name 'name'*/
void register_object(struct object *x,char *name)
{
	int i;
	for(i=NULL;i<MAX_OBJ && obj_desc[i].x;i++);
	obj_desc[i].x=x;
	strcpy(obj_desc[i].desc,name);
}

/*Deletes an entry in the table*/
void unregister_object(struct object *x)
{
	int i;
	for(i=NULL;i<MAX_OBJ;i++)	{
		if(obj_desc[i].x==x)	{
			obj_desc[i].x=NULL;
			break;
		}
	}
}
	
/*This gets the descriptor for the object requested. **Needs hashing.*/
char *get_obj_desc(struct object *x)
{
	int i;
	for(i=NULL;i<MAX_OBJ;i++)	{
		if(obj_desc[i].x==x)
			return obj_desc[i].desc;
	}
	return NULL;
}

struct object *get_object(char *desc)
{
	int i;
	for(i=NULL;i<MAX_OBJ;i++)	{
		if(!strcmp(obj_desc[i].desc,desc))
			return obj_desc[i].x;
	}
	return NULL;
}

/*Make all null entries in the object descriptor table*/
void init_obj_desc()
{
	memset(obj_desc,NULL,sizeof(struct obj_desctable)*MAX_OBJ);
}

/*Initiate members of and object, make pointers null*/
void init_object(struct object *x)
{
	memset(x,NULL,sizeof(struct object));
}

/*Construct the link structure*/
void init_object_link(struct link *x)
{
	memset(x,NULL,sizeof(struct link));
}

/*Create a new object and construct the members*/
struct object *create_object()
{
	struct object *x;
	x=(struct object *)malloc(sizeof(struct object));
	init_object(x);
	return x;
}

/*Creates a new link*/
struct link *create_link()
{
	struct link *x;
	x=(struct link *)malloc(sizeof(struct object));
	init_object_link(x);
	return x;
}

int get_free_link(struct object *x)
{
	int i;
	for(i=NULL;i<MAX_LINK;i++)	{
		if(!(x->links[i]))
			return i;
	}
}

/*Initiates the initial system with the sys object and the core objects.
Returns the sys pointer*/
struct object *init_sys()
{
	struct object *x;
	init_obj_desc();
	x=create_object();
	/*sys object is the main object to which control is passed*/
	register_object(x,"sys");
	return x;
}

/*Execution system for RPS*/
/*This function is added as a thread to the host operating system. For concurrent links this function forks.*/
volatile struct object *main;

void control_rps()
{
	printk("AA");
}

/*-------------------------Object display functions & user interface: OS dependent frontend--------------------*/

#define USR_INP 256
#define ERROR -1

char *LTC_usr[]={"NoCondition","Condition"};
char *LTT_usr[]={"Sequential","Concurrent","Dead"};
char *CON_usr[]={"=",">","<",">=","<="};
char *LT_usr_inp[]={"-","|","."};	//Sequential,Concurrent and Dead link representations at commandline

#define CON_CNT 5
#define LT_CNT 3

/*Displays the contents of an object in detail*/
int display_object(struct object *x)
{
	char *desc;
	struct data_lp *t;
	int i;
	if(!(desc=get_obj_desc(x)))	{	/*Get the object descriptor from the table*/
		printk("\nObject not found/not registered");
		return ERROR;
	}
	printk("\n%s",desc);
	for(i=NULL;i<MAX_LINK;i++)	{
		if(x->links[i])	{
			if(!(desc=get_obj_desc(x->links[i]->link_object)))	{	/*Find the descriptor of the object that this object is linking to*/
				printk("\n-Link object not found");
				continue;
			}
			printk("\n-%s %s,%s",desc,LTC_usr[x->links[i]->link_type & 1],LTT_usr[x->links[i]->link_type & 0x10]);				
		}
	}
	return NULL;
}

/*List display functions to simply display the names of the objects registered*/
int display_list()
{
	int i;
	for(i=NULL;i<MAX_OBJ;i++)	{
		if(obj_desc[i].x)
			printk("\n%s",obj_desc[i].desc);
	}
}

/*Main commandline interface*/
void show_mem()
{
	printk("\nMemory");
	printk("\nTotal:%d kB (%d B)",(sys_occ()+mem_occ())/1024,sys_occ()+mem_occ());
	printk("\nSystem:%d kB (%d B)",sys_occ()/1024,sys_occ());
	printk("\nSystem allocations:%d kB (%d B)",mem_occ()/1024,mem_occ());
}

void cl()
{
	struct object *cur;
	int i;
	char ret[20];
	cur=init_sys();
	clrscr();
	printk("Menu:");
	addopt(3,"Halt\nReboot\nGUI");
	i=getopt();
	switch(i)	{
		case 0:	halt(0);
		case 1:	reboot();
		case 2:	init_ui(800,600,0);
				break;
	}
}
